﻿using System;
using System.Linq;
using System.ServiceModel;
using ProLinq.Wcf.Sample.Service;

namespace ProLinq.Wcf.Sample.Client
{
	class Program
	{
		private Int32 _someProdId = 2;

		static void Main(string[] args)
		{
			var channelFactory = new QueryableChannelFactory<ISampleService>(new BasicHttpBinding());
			var channel = channelFactory.CreateChannel(new EndpointAddress("http://localhost:61077/SampleService.svc"));

			// Case 1 : Count
			var c = channel.GetProducts().Count();
			Console.WriteLine("Products count: {0}", c);
			Console.WriteLine();

			// Case 2: Filter + Sorting + Paging
			Console.WriteLine("3 most expensive food products: ");
			var prods = channel.GetProducts().Where(p => p.CategoryId == 1).OrderByDescending(a => a.Price).Take(3);
			foreach (var p in prods)
			{
				Console.Write("{0}, ", p.Name);
			}
			Console.WriteLine();


			// Case 3: Anonymous types
			Console.WriteLine("Products total value: ");
			var res1 = from p in channel.GetProducts()
					   select new
						   {
							   p.Name,
							   TotalValue = p.Price * p.StockCount
						   };
			foreach (var r in res1)
			{
				Console.WriteLine("{0}: {1} ", r.Name, r.TotalValue);
			}
			Console.WriteLine();


			// Case 4: Joins
			Console.WriteLine("Product categories: ");
			var res2 = from p in channel.GetProducts()
					   join c1 in channel.GetCategories() on p.CategoryId equals c1.Id
					   select new
					   {
						   Product = p,
						   Category = c1
					   };

			foreach (var r in res2)
			{
				Console.WriteLine("{0}: {1} ", r.Product.Name, r.Category.Name);
			}
			Console.WriteLine();


			// Case 5: Out parameter
			Console.WriteLine("Get Product count again, but in output parameter: ");
			Int32 c2;
			channel.GetProductCountOut(out c2);
			Console.WriteLine("Count: {0}", c2);
			Console.WriteLine();


			// Case 6: Partial Evaluation
			var prog = new Program();
			Console.WriteLine("Get Product by id stored in a non-serializable class field.");
			var p1 = channel.GetProducts().Where(p => p.Id == prog._someProdId).FirstOrDefault();
			Console.WriteLine("Product name: {0}", p1.Name);
			Console.WriteLine();
		}
	}
}
